package day10.test3;

public class Run {
    public static void main(String[] args) {
        try {
            DealThread t1 = new DealThread();
            t1.setFlag("a");

            Thread thread1 = new Thread(t1);
            thread1.start();

            Thread.sleep(100);

            t1.setFlag("b");

            Thread thread2 = new Thread(t1);
            thread2.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class DealThread implements Runnable {
    public String username;
    public Object lock1 = new Object();
    public Object lock2 = new Object();

    public void setFlag(String username) {
        this.username = username;
    }

    @Override
    public void run() {
        if (username.equals("a")) {
            synchronized (lock1) {
                try {
                    System.out.println("username = " + username);
                    lock1.wait();
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("a抢到资源了");
                }
            }
        }
        if (username.equals("b")) {
            synchronized (lock2) {
                try {
                    System.out.println("username = " + username);
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("b抢到资源了");
                    lock1.notify();
                }
            }
        }
    }
}
/*
1. 代码执行顺序与线程启动
当执行thread2.start()时，thread2线程开始执行DealThread类的run方法。然而，run方法内部的执行情况比较复杂。
2. 共享Runnable对象的问题
由于DealThread实例t1被thread1和thread2共享，在thread2执行run方法期间，thread2可能会因为线程调度而暂停执行。
这里并不是说thread2再次启动，而是在thread2的一次执行过程中，由于线程调度，它可能会被暂停然后重新获得 CPU 时间片继续执行。
在thread2执行run方法的过程中（例如，在获取lock1锁之后，执行Thread.sleep(300)期间），它仍然处于run方法的执行流程中。
当thread2从睡眠中恢复时，它继续执行后续的代码（获取lock2锁等）。
但在某些情况下，由于线程调度的不确定性，thread2在还没有完全执行完run方法一次完整的流程时，可能会在同一个时间片内或者后续重新获得时间片时，
继续执行run方法中的代码（因为run方法没有结束，它所属的线程仍然关联着这个Runnable对象的执行逻辑）。
*这就导致了看起来像是thread2多次启动的假象，实际上是thread2在一次启动后的复杂执行流程中出现的问题。
3. 同步和阻塞的影响
这种情况在多线程同步代码中更容易出现问题。synchronized块和锁的使用，使得线程在获取锁和等待锁释放的过程中，其执行流程会受到很大影响。
在这个例子中，lock1和lock2锁的使用，以及Runnable对象的共享，共同导致了这种复杂且不符合预期的执行结果。
* */